package com.ebupt.migu.music.commons.selfdom.demo.impl.identifier;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ebupt.migu.globalpopup.enums.FileTypeEnum;
import com.ebupt.migu.globalpopup.enums.IdentifierEnum;
import com.ebupt.migu.music.commons.utils.SpringContextUtil;
import com.ebupt.migu.music.commons.utils.TxtUtil;
import com.ebupt.migu.music.commons.utils.PathBuffer;
import com.ebupt.migu.music.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 标准字符类型实现类
 *
 * @author wangzhu
 * @since 2021-12-31
 */
@Slf4j
@Component
@DependsOn("springContextUtil")
public  class AbstractIdentifierImpl extends AbstractIdentifier {

    private final RedisService redisService = SpringContextUtil.getBean("redisService");

    /**
     * 等于
     */
    private boolean equalTo(String source, String target) {return source.equals(target);
    }

    /**
     * 不等于
     */
    private boolean noEqualTo(String source, String target) {
        return !source.equals(target);
    }

    /**
     * 列表等于(文件)
     */
    private boolean listEqualTo(String source, String target) {
        if(target==null){
            String file = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH") + FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile()+"/"+target;
            TxtUtil txtUtil = TxtUtil.getTxtUtil();
            List list = txtUtil.toList(new File(file));
            return list.contains(source);
        }
        String regex = ".*\\d{13}.*";
        if(Pattern.matches(regex, target)){//新的判断规则
            String filePath = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH") + FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile() + "/" + target;
//        String filePath = "D:\\apps\\shared\\fine-operation-label\\upload\\global\\" + target;
            // 从redis读取数据，转为List
            long startTime = System.currentTimeMillis();
            boolean member = redisService.isMember(filePath, source);
            long jiaoyanTime = System.currentTimeMillis();
            if(startTime%100==1){
                redisService.setExpireForDay(filePath,90L);
            }
            long guoqiTime = System.currentTimeMillis();
            long jiaoyanHaomiao = jiaoyanTime - startTime;
            long guoqiHaomiao = guoqiTime - jiaoyanTime;
            log.info("文件校验用时：{}毫秒过期用时毫秒{}",jiaoyanHaomiao,guoqiHaomiao);
            return member;
        }else {//原来的判断规则
            String file = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH") + FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile()+"/"+target;
            TxtUtil txtUtil = TxtUtil.getTxtUtil();
            List list = txtUtil.toList(new File(file));
            return list.contains(source);
        }
//        Object files = redisService.getSet(filePath);
//        if (files == null) {
//            TxtUtil txtUtil = TxtUtil.getTxtUtil();
//            List list = txtUtil.toList(new File(filePath));
//            return list.contains(source);
//        }
//        Set set = (Set) files;
//        return set.contains(source);
    }
    /**
     * 列表不等于(文件)
     */
    private boolean listNoEqualTo(String source, String target) {
        if(target==null){
            String file = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH")+ FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile()+"/"+target;
            TxtUtil txtUtil = TxtUtil.getTxtUtil();
            List list = txtUtil.toList(new File(file));
            return !list.contains(source);
        }
        String regex = ".*\\d{13}.*";
        if(Pattern.matches(regex, target)) {//新的判断规则
            String filePath = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH") + FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile() + "/" + target;
//        String filePath = "D:\\apps\\shared\\fine-operation-label\\upload\\global\\" + target;
            // 从redis读取数据，转为List
            long startTime = System.currentTimeMillis();
            boolean member = redisService.isMember(filePath, source);
            long jiaoyanTime = System.currentTimeMillis();
            if(startTime%100==1){
                redisService.setExpireForDay(filePath,90L);
            }
            long guoqiTime = System.currentTimeMillis();
            long jiaoyanHaomiao = jiaoyanTime - startTime;
            long guoqiHaomiao = guoqiTime - jiaoyanTime;
            log.info("文件校验用时：{}毫秒过期用时毫秒{}",jiaoyanHaomiao,guoqiHaomiao);
            return !member;
        }else {
            String file = PathBuffer.NUMBERLOCATION.get("FILE_GLOBAL_PATH")+ FileTypeEnum.FILE_TYPE_ENUM_TXT.getFile()+"/"+target;
            TxtUtil txtUtil = TxtUtil.getTxtUtil();
            List list = txtUtil.toList(new File(file));
            return !list.contains(source);
        }
//        Object files = redisService.getSet(filePath);
//        if (files == null) {
//            TxtUtil txtUtil = TxtUtil.getTxtUtil();
//            List list = txtUtil.toList(new File(filePath));
//            return !list.contains(source);
//        }
//        Set set = (Set) files;
//        return !set.contains(source);
    }

    /**
     * 列表等于（人群）
     *
     * @param source 用户uid或手机号对应的值
     * @param groupId 人群id
     * @return 在人群中返回true，不在返回false
     */
    public boolean userGroupEqualTo(String source, String groupId)  {
        // 分别从redis获取uid、手机号、idfa的key，判断value在不在key中
        String phoneKey = groupId + "-phone";
        String imeiKey = groupId + "-imei";
        String uidKey = groupId + "-uid";
        boolean flag1 = false;
        boolean flag2 = false;
        boolean flag3 = false;
        if (redisService.exists(phoneKey)) {
            flag1 = redisService.isMember(phoneKey, source);
        }
        if (redisService.exists(imeiKey)) {
            flag2 = redisService.isMember(imeiKey, source);
        }
        if (redisService.exists(uidKey)) {
            flag3 = redisService.isMember(uidKey, source);
        }
        return (flag1 || flag2 || flag3);
    }

    /**
     * 列表等于（FTP上传人群）
     *
     * @param source 用户uid或手机号对应的值
     * @param target redis的key值
     * @return 在人群中返回true，不在返回false
     */
    private boolean ftpGroupEqualTo(String source, String target) {
        long startTime = System.currentTimeMillis();
        boolean flag = redisService.isMember(target, source);
        long jiaoyanTime = System.currentTimeMillis();
        if(startTime%100==1){
            redisService.setExpireForDay(target, 90L);
        }
        long guoqiTime = System.currentTimeMillis();
        long jiaoyanHaomiao = jiaoyanTime - startTime;
        long guoqiHaomiao = guoqiTime - jiaoyanTime;
        log.info("ftp校验用时：{}毫秒过期用时毫秒{}",jiaoyanHaomiao,guoqiHaomiao);
        return flag;
    }

    /**
     * 更具不同的判断方法返回判断结果
     */
    @Override
    public boolean getIdentifier(String source, String target, Integer identifier, Integer conditionKey) {
        boolean b = true;
        switch (identifier) {
            case 1:
                b = this.equalTo(source, target);
                break;
            case 6:
                b = this.noEqualTo(source, target);
                break;
            case 7:
                b = this.listEqualTo(source, target);
                break;
            case 8:
                b = this.listNoEqualTo(source, target);
                break;
            case 22:
                b = this.userGroupEqualTo(source, target);
                break;
            case 23:
                b = !(this.userGroupEqualTo(source, target));
                break;
            case 24:
                b = this.ftpGroupEqualTo(source, target);
                break;
            case 25:
                b = !(this.ftpGroupEqualTo(source, target));
                break;
            default:
                break;
        }
        log.info("判断条件:{},对比参数:{},目标参数:{},对比结果:{}", IdentifierEnum.getCodeByName(identifier),source,target,b);
        return b;
    }

    @Override
    public boolean getRelation(LinkedHashMap<Boolean,Integer> map) {
        boolean t = true;
        Iterator<Map.Entry<Boolean, Integer>> iterator = map.entrySet().iterator();
        int  size=0;
        while (iterator.hasNext()) {
            Map.Entry<Boolean, Integer> next = iterator.next();
            if(size==0) {
                t = next.getKey();
            }
            //and
            if (next.getValue() == 1) {
                t = t && next.getKey();
            }
            //or
            if (next.getValue() == 2) {
                t = t || next.getKey();
            }
            size+=1;
        }
        return t;
    }

    @Override
    public <T> void sort(List<T> list) {
//        log.info("排序前集合:{},数量:{}",list, list.size() );
        list.sort((x,y)->{
            int compare = 0;
            JSONObject xparse = JSONObject.parseObject(JSON.toJSONString(x));
            JSONObject yparse =JSONObject.parseObject(JSON.toJSONString(y));
            if (xparse.get("conditionKey") != null && yparse.get("conditionKey")!=null) {
                Integer xconditionKey = Integer.valueOf(xparse.get("conditionKey").toString());
                Integer yconditionKey = Integer.valueOf(yparse.get("conditionKey").toString());
                compare = Integer.compare(xconditionKey, yconditionKey);
            }
            return compare;
        });
//        log.info("排序后集合:{},数量:{}",list, list.size() );
    }

}
